#!/bin/bash

# Claude Code 镜像同步脚本 (Mac/Linux版本)
# 从官方 Google Cloud Storage 下载文件并上传到 Gitee Release

set -e

# 默认参数
OUTPUT_DIR="./claude-mirror"
DOWNLOAD_ALL_PLATFORMS=true  # 默认下载所有平台
AUTO_COMMIT=false
GITEE_REPO=""
GITEE_TOKEN=""
UPLOAD_TO_RELEASE=false
DELETE_EXISTING_RELEASE=false

# 解析命令行参数
while [[ $# -gt 0 ]]; do
    case $1 in
        -o|--output-dir)
            OUTPUT_DIR="$2"
            shift 2
            ;;
        -a|--all-platforms)
            DOWNLOAD_ALL_PLATFORMS=true
            shift
            ;;
        -c|--auto-commit)
            AUTO_COMMIT=true
            shift
            ;;
        -r|--gitee-repo)
            GITEE_REPO="$2"
            shift 2
            ;;
        -t|--gitee-token)
            GITEE_TOKEN="$2"
            shift 2
            ;;
        --upload-to-release)
            UPLOAD_TO_RELEASE=true
            shift
            ;;
        --delete-existing)
            DELETE_EXISTING_RELEASE=true
            shift
            ;;
        -h|--help)
            echo "用法: $0 [选项]"
            echo ""
            echo "选项:"
            echo "  -o, --output-dir DIR         输出目录 (默认: ./claude-mirror)"
            echo "  -a, --all-platforms          下载所有平台的文件 (默认: true)"
            echo "  -c, --auto-commit            自动提交到 Gitee"
            echo "  -r, --gitee-repo REPO        Gitee 仓库地址"
            echo "  -t, --gitee-token TOKEN      Gitee API Token"
            echo "      --upload-to-release      上传到 Release 页面而非仓库"
            echo "      --delete-existing        删除已存在的 Release"
            echo "  -h, --help                  显示此帮助信息"
            echo ""
            echo "示例:"
            echo "  $0                                                       # 下载所有平台文件"
            echo "  $0 -t YOUR_TOKEN -r https://gitee.com/user/repo.git \\"
            echo "     --upload-to-release                                    # 下载并上传到 Release"
            echo "  $0 -t YOUR_TOKEN -r https://gitee.com/user/repo.git \\"
            echo "     --upload-to-release --delete-existing                  # 删除现有 Release 并重新上传"
            exit 0
            ;;
        *)
            echo "未知参数: $1"
            echo "使用 -h 或 --help 查看帮助"
            exit 1
            ;;
    esac
done

GCS_BUCKET="https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases"

echo "======================================"
echo "  Claude Code Gitee 镜像同步工具"
echo "  (Mac/Linux 版本)"
echo "======================================"
echo ""

# 检查依赖
check_dependency() {
    local cmd="$1"
    local name="$2"

    if ! command -v "$cmd" >/dev/null 2>&1; then
        echo "错误: 需要安装 $name" >&2
        echo "  macOS: brew install $name" >&2
        echo "  Ubuntu/Debian: sudo apt-get install $name" >&2
        echo "  CentOS/RHEL: sudo yum install $name" >&2
        exit 1
    fi
}

check_dependency "curl" "curl"
check_dependency "jq" "jq"

# 检查是否提供了必要的参数
if [ "$UPLOAD_TO_RELEASE" = true ]; then
    if [ -z "$GITEE_TOKEN" ]; then
        echo "错误: 上传到 Release 需要提供 Gitee API Token"
        echo "请使用 -t 参数提供 token，或设置 GITEE_TOKEN 环境变量"
        exit 1
    fi

    if [ -z "$GITEE_REPO" ]; then
        echo "错误: 上传到 Release 需要提供 Gitee 仓库地址"
        echo "请使用 -r 参数提供仓库地址"
        exit 1
    fi
fi

# Gitee API 函数
extract_repo_info() {
    local repo_url="$1"
    # 从 https://gitee.com/user/repo.git 提取 user/repo
    local path=$(echo "$repo_url" | sed 's|.*gitee\.com/||' | sed 's|\.git||')

    if [[ -z "$path" || "$path" != *"/"* ]]; then
        echo "错误: 无效的 Gitee 仓库地址: $repo_url" >&2
        echo "期望格式: https://gitee.com/user/repo.git" >&2
        exit 1
    fi

    echo "$path"
}

delete_existing_release() {
    local repo_path="$1"
    local tag="$2"

    echo "  检查是否存在现有 Release: $tag"

    # 获取现有的 Release ID
    release_url="https://gitee.com/api/v5/repos/$repo_path/releases/tags/$tag"

    if release_info=$(curl -s -H "Authorization: token $GITEE_TOKEN" "$release_url" 2>/dev/null); then
        if echo "$release_info" | jq -e '.id' >/dev/null 2>&1; then
            release_id=$(echo "$release_info" | jq -r '.id')
            echo "    找到现有 Release ID: $release_id"

            # 删除现有 Release
            delete_url="https://gitee.com/api/v5/repos/$repo_path/releases/$release_id"
            if curl -s -X DELETE -H "Authorization: token $GITEE_TOKEN" "$delete_url" >/dev/null 2>&1; then
                echo "    ✓ 已删除现有 Release"
            else
                echo "    ✗ 删除现有 Release 失败"
                return 1
            fi
        else
            echo "    未找到现有 Release"
        fi
    else
        echo "    无法检查现有 Release"
    fi
}

create_release() {
    local repo_path="$1"
    local tag="$2"
    local name="$3"
    local body="$4"

    echo "  创建 Release: $tag"

    create_url="https://gitee.com/api/v5/repos/$repo_path/releases"

    release_data=$(jq -n \
        --arg tag_name "$tag" \
        --arg name "$name" \
        --arg body "$body" \
        '{
            "tag_name": $tag_name,
            "name": $name,
            "body": $body,
            "prerelease": false
        }')

    if response=$(curl -s -X POST \
        -H "Authorization: token $GITEE_TOKEN" \
        -H "Content-Type: application/json" \
        -d "$release_data" \
        "$create_url"); then

        if echo "$response" | jq -e '.id' >/dev/null 2>&1; then
            release_id=$(echo "$response" | jq -r '.id')
            upload_url=$(echo "$response" | jq -r '.upload_url' | sed 's/{?name,label}//')
            echo "    ✓ Release 创建成功，ID: $release_id"
            echo "$upload_url"
            return 0
        else
            echo "    ✗ Release 创建失败"
            echo "$response" | jq -r '.message // "未知错误"' >&2
            return 1
        fi
    else
        echo "    ✗ API 调用失败"
        return 1
    fi
}

upload_asset() {
    local repo_path="$1"
    local release_id="$2"
    local file_path="$3"
    local content_type="$4"

    local filename=$(basename "$file_path")
    local file_size=$(stat -c %s "$file_path" 2>/dev/null || stat -f %z "$file_path" 2>/dev/null || echo "0")

    echo "    上传文件: $filename (${file_size} bytes)"

    upload_url="https://gitee.com/api/v5/repos/$repo_path/releases/$release_id/assets"

    # Gitee 使用不同的上传方式
    if response=$(curl -s -X POST \
        -H "Authorization: token $GITEE_TOKEN" \
        -F "file=@$file_path" \
        "$upload_url"); then

        if echo "$response" | jq -e '.id' >/dev/null 2>&1; then
            download_url=$(echo "$response" | jq -r '.browser_download_url')
            echo "      ✓ 上传成功: $download_url"
            return 0
        else
            echo "      ✗ 上传失败"
            echo "$response" | jq -r '.message // "未知错误"' >&2
            return 1
        fi
    else
        echo "      ✗ 上传 API 调用失败"
        return 1
    fi
}

# 创建输出目录
echo "[1/7] 创建输出目录: $OUTPUT_DIR"
mkdir -p "$OUTPUT_DIR"

# 获取稳定版本号
echo "[2/7] 获取稳定版本号..."
if ! version=$(curl -fsSL "$GCS_BUCKET/stable"); then
    echo "错误: 无法获取版本号。请检查网络连接或使用代理。" >&2
    exit 1
fi
echo "      稳定版本: $version"

# 保存版本号文件
echo "$version" > "$OUTPUT_DIR/stable"
echo "      已保存 stable 文件"

# 获取 latest 版本号（可选）
if latest=$(curl -fsSL "$GCS_BUCKET/latest" 2>/dev/null); then
    echo "$latest" > "$OUTPUT_DIR/latest"
    echo "      最新版本: $latest"
else
    echo "      警告: 无法获取 latest 版本号（可能不存在）"
fi

# 创建版本目录
version_dir="$OUTPUT_DIR/$version"
mkdir -p "$version_dir"

# 下载 manifest.json
echo "[3/7] 下载 manifest.json..."
manifest_url="$GCS_BUCKET/$version/manifest.json"
if ! curl -fsSL "$manifest_url" -o "$version_dir/manifest.json"; then
    echo "错误: 下载 manifest.json 失败" >&2
    exit 1
fi
echo "      已下载 manifest.json"

# 读取并显示 manifest 信息
if ! manifest_json=$(cat "$version_dir/manifest.json"); then
    echo "错误: 无法读取 manifest.json" >&2
    exit 1
fi

echo "      可用平台:"
if command -v jq >/dev/null 2>&1; then
    echo "$manifest_json" | jq -r '.platforms | keys[]' | sed 's/^/        - /'
else
    echo "$manifest_json" | grep -o '"[^"]*":' | grep -v 'checksum' | sed 's/[":]//g' | sed 's/^/        - /'
fi

# 检测当前平台
echo "[4/7] 检测当前平台..."
detect_platform() {
    local os=""
    local arch=""

    case "$(uname -s)" in
        Darwin) os="darwin" ;;
        Linux) os="linux" ;;
        *)
            echo "错误: 不支持的操作系统: $(uname -s)" >&2
            exit 1
            ;;
    esac

    case "$(uname -m)" in
        x86_64|amd64) arch="x64" ;;
        arm64|aarch64) arch="arm64" ;;
        *)
            echo "错误: 不支持的架构: $(uname -m)" >&2
            exit 1
            ;;
    esac

    # 检查 musl (仅限 Linux)
    if [ "$os" = "linux" ]; then
        if [ -f /lib/libc.musl-x86_64.so.1 ] || [ -f /lib/libc.musl-aarch64.so.1 ] || ldd /bin/ls 2>&1 | grep -q musl; then
            platform="linux-${arch}-musl"
        else
            platform="linux-${arch}"
        fi
    else
        platform="${os}-${arch}"
    fi

    echo "$platform"
}

current_platform=$(detect_platform)
echo "      当前平台: $current_platform"

# 确定要下载的平台
platforms=()
if [ "$DOWNLOAD_ALL_PLATFORMS" = true ]; then
    # 下载所有平台
    if command -v jq >/dev/null 2>&1; then
        # 使用更兼容的方式读取平台列表
        platforms=($(echo "$manifest_json" | jq -r '.platforms | keys[]'))
    else
        # 简单的 JSON 解析（备用方案）
        platforms=$(echo "$manifest_json" | grep -o '"[^"]*":{' | grep -v 'checksum' | sed 's/[":{]//g')
    fi
    echo "      将下载所有平台的文件"
else
    # 只下载当前平台
    platforms=("$current_platform")
    echo "      将下载当前平台: $current_platform (使用 -a 下载所有平台)"
fi

# 下载二进制文件
echo "[5/7] 下载二进制文件..."
downloaded_files=()

for platform in "${platforms[@]}"; do
    echo "      处理 $platform..."

    platform_dir="$version_dir/$platform"
    mkdir -p "$platform_dir"

    # 根据平台确定文件名和扩展名
    if [[ "$platform" == win32* ]]; then
        binary_name="claude.exe"
    else
        binary_name="claude"
    fi

    binary_url="$GCS_BUCKET/$version/$platform/$binary_name"
    binary_path="$platform_dir/$binary_name"

    # 获取期望的校验和
    if command -v jq >/dev/null 2>&1; then
        expected_checksum=$(echo "$manifest_json" | jq -r ".platforms[\"$platform\"].checksum // empty")
    else
        # 简单的正则表达式提取（备用方案）
        expected_checksum=$(echo "$manifest_json" | grep -A 5 "\"$platform\"" | grep '"checksum"' | grep -o '[a-f0-9]\{64\}')
    fi

    # 检查文件是否已存在并验证完整性
    skip_download=false
    if [ -f "$binary_path" ]; then
        echo "        发现已存在的文件，检查完整性..."

        # 检查文件大小（避免0字节文件）
        if [ -s "$binary_path" ]; then
            # 计算现有文件的校验和
            if command -v sha256sum >/dev/null 2>&1; then
                actual_checksum=$(sha256sum "$binary_path" | cut -d' ' -f1)
            elif command -v shasum >/dev/null 2>&1; then
                actual_checksum=$(shasum -a 256 "$binary_path" | cut -d' ' -f1)
            else
                echo "        警告: 无法验证校验和，缺少 sha256sum 或 shasum 命令"
                actual_checksum=""
            fi

            # 验证校验和
            if [ -n "$actual_checksum" ] && [ -n "$expected_checksum" ] && [ "$actual_checksum" = "$expected_checksum" ]; then
                echo "        ✓ 文件完整性验证通过，跳过下载"
                skip_download=true
            elif [ -z "$expected_checksum" ]; then
                echo "        警告: 无法获取期望的校验和，重新下载文件"
            else
                echo "        × 文件损坏或不完整，需要重新下载"
                if [ -n "$actual_checksum" ]; then
                    echo "          期望: $expected_checksum"
                    echo "          实际: $actual_checksum"
                fi
                # 删除损坏的文件
                rm -f "$binary_path"
            fi
        else
            echo "        文件为空，需要重新下载"
            rm -f "$binary_path"
        fi
    fi

    # 如果需要下载
    if [ "$skip_download" = false ]; then
        echo "        从 $binary_url"

                    if curl -fsSL "$binary_url" -o "$binary_path"; then
            # 验证下载文件的校验和
            if command -v sha256sum >/dev/null 2>&1; then
                actual_checksum=$(sha256sum "$binary_path" | cut -d' ' -f1)
            elif command -v shasum >/dev/null 2>&1; then
                actual_checksum=$(shasum -a 256 "$binary_path" | cut -d' ' -f1)
            else
                echo "        警告: 无法验证校验和，缺少 sha256sum 或 shasum 命令"
                actual_checksum=""
            fi

            if [ -n "$actual_checksum" ] && [ -n "$expected_checksum" ] && [ "$actual_checksum" = "$expected_checksum" ]; then
                echo "        ✓ 下载完成，校验和验证通过"
            else
                echo "        × 下载的文件校验和不匹配！"
                [ -n "$expected_checksum" ] && echo "          期望: $expected_checksum"
                [ -n "$actual_checksum" ] && echo "          实际: $actual_checksum"
                rm -f "$binary_path"
            fi
        else
            echo "        警告: 下载 $platform 失败"
        fi
    fi

    # 如果文件存在且完整，添加到下载列表
    if [ -f "$binary_path" ] && [ -s "$binary_path" ]; then
        # 显示文件大小
        if command -v stat >/dev/null 2>&1; then
            if stat -c %s "$binary_path" >/dev/null 2>&1; then
                # Linux
                file_size=$(stat -c %s "$binary_path")
            else
                # macOS
                file_size=$(stat -f %z "$binary_path")
            fi
            file_size_mb=$(echo "scale=2; $file_size / 1048576" | bc 2>/dev/null || echo "N/A")
            echo "        文件大小: ${file_size_mb} MB"
        fi

        # 记录下载的文件
        downloaded_files+=("$binary_path")

        # 设置可执行权限（非 Windows 文件）
        if [ "$binary_name" != "claude.exe" ]; then
            chmod +x "$binary_path"
        fi
    fi
done

# 生成 checksums.txt 文件
echo "[6/7] 生成 checksums.txt..."
checksums_file="$version_dir/checksums.txt"
echo "# Claude Code $version Checksums" > "$checksums_file"
echo "# Generated on $(date)" >> "$checksums_file"
echo "" >> "$checksums_file"

for file_path in "${downloaded_files[@]}"; do
    if [ -f "$file_path" ]; then
        if command -v sha256sum >/dev/null 2>&1; then
            checksum=$(sha256sum "$file_path" | cut -d' ' -f1)
        elif command -v shasum >/dev/null 2>&1; then
            checksum=$(shasum -a 256 "$file_path" | cut -d' ' -f1)
        else
            echo "        警告: 无法生成校验和，缺少 sha256sum 或 shasum 命令"
            continue
        fi

        filename=$(basename "$file_path")
        echo "$checksum  $filename" >> "$checksums_file"
        echo "        已添加: $filename"
    fi
done

# 生成文件清单
echo "[7/7] 生成文件清单..."
files_manifest="$OUTPUT_DIR/files-manifest.json"

# 创建 JSON 清单
echo "{" > "$files_manifest"
echo "  \"version\": \"$version\"," >> "$files_manifest"
echo "  \"syncTime\": \"$(date '+%Y-%m-%d %H:%M:%S')\"," >> "$files_manifest"
echo "  \"platform\": \"$(uname -s)-$(uname -m)\"," >> "$files_manifest"
echo "  \"files\": [" >> "$files_manifest"

# 添加文件信息
first=true
find "$OUTPUT_DIR" -type f | while read -r file; do
    if [ "$first" = true ]; then
        first=false
    else
        echo "," >> "$files_manifest"
    fi

    relative_path="${file#$OUTPUT_DIR/}"
    if command -v stat >/dev/null 2>&1; then
        if stat -c %s "$file" >/dev/null 2>&1; then
            # Linux
            file_size=$(stat -c %s "$file")
        else
            # macOS
            file_size=$(stat -f %z "$file")
        fi
    else
        file_size=0
    fi

    if command -v sha256sum >/dev/null 2>&1; then
        file_checksum=$(sha256sum "$file" | cut -d' ' -f1)
    elif command -v shasum >/dev/null 2>&1; then
        file_checksum=$(shasum -a 256 "$file" | cut -d' ' -f1)
    else
        file_checksum=""
    fi

    echo "    {" >> "$files_manifest"
    echo "      \"path\": \"$relative_path\"," >> "$files_manifest"
    echo "      \"size\": $file_size," >> "$files_manifest"
    echo "      \"checksum\": \"$file_checksum\"" >> "$files_manifest"
    echo -n "    }" >> "$files_manifest"
done

echo "" >> "$files_manifest"
echo "  ]" >> "$files_manifest"
echo "}" >> "$files_manifest"

echo "      已生成文件清单: files-manifest.json"

# 显示目录结构
echo ""
echo "文件下载完成！"
echo ""
echo "目录结构:"
if command -v tree >/dev/null 2>&1; then
    tree "$OUTPUT_DIR"
else
    find "$OUTPUT_DIR" -type f | sort
fi

echo ""
echo "======================================"
echo "  下一步操作"
echo "======================================"
echo ""

if [ "$UPLOAD_TO_RELEASE" = true ] && [ -n "$GITEE_REPO" ] && [ -n "$GITEE_TOKEN" ]; then
    echo "上传到 Gitee Release 页面..."

    # 提取仓库信息
    repo_path=$(extract_repo_info "$GITEE_REPO")
    echo "  仓库路径: $repo_path"

    # 删除现有 Release（如果需要）
    if [ "$DELETE_EXISTING_RELEASE" = true ]; then
        delete_existing_release "$repo_path" "$version"
    fi

    # 创建 Release
    release_name="Claude Code $version"
    release_body="Claude Code 版本 $version

## 支持的平台
$(for platform in "${platforms[@]}"; do echo "- $platform"; done)

## 文件说明
- checksums.txt: 所有文件的 SHA256 校验和
- 各平台的 claude 二进制文件

## 安装方法
\`\`\`bash
# 下载并安装 Claude Code
curl -fsSL https://gitee.com/$repo_path/raw/main/bootstrap.sh | bash
\`\`\`

---
同步时间: $(date '+%Y-%m-%d %H:%M:%S')"

    if upload_url=$(create_release "$repo_path" "$version" "$release_name" "$release_body"); then
        release_id=$(echo "$upload_url" | jq -r '.id // empty')
        if [ -n "$release_id" ]; then
            upload_url=$(echo "$upload_url" | jq -r '.upload_url // empty')
        fi

        # 上传文件到 Release
        echo "  上传文件到 Release..."

        upload_failed=false

        # 上传 checksums.txt
        if [ -f "$checksums_file" ]; then
            if ! upload_asset "$repo_path" "$release_id" "$checksums_file" "text/plain"; then
                upload_failed=true
            fi
        fi

        # 上传所有二进制文件
        for file_path in "${downloaded_files[@]}"; do
            if [ -f "$file_path" ]; then
                # 确定内容类型
                if [[ "$file_path" == *.exe ]]; then
                    content_type="application/octet-stream"
                else
                    content_type="application/octet-stream"
                fi

                if ! upload_asset "$repo_path" "$release_id" "$file_path" "$content_type"; then
                    upload_failed=true
                fi
            fi
        done

        if [ "$upload_failed" = false ]; then
            echo ""
            echo "  ✓ 所有文件上传成功！"
            echo ""
            echo "  Release 页面: https://gitee.com/$repo_path/releases/tag/$version"
            echo ""
            echo "  用户现在可以使用以下命令安装:"
            echo "  curl -fsSL https://gitee.com/$repo_path/raw/main/bootstrap.sh | bash"
        else
            echo ""
            echo "  ✗ 部分文件上传失败，请检查错误信息"
            exit 1
        fi
    else
        echo "错误: 创建 Release 失败"
        exit 1
    fi

elif [ "$AUTO_COMMIT" = true ] && [ -n "$GITEE_REPO" ]; then
    echo "自动提交到 Gitee 仓库..."

    temp_clone_dir="./gitee-temp"

    # 清理可能存在的临时目录
    rm -rf "$temp_clone_dir"

    if git clone "$GITEE_REPO" "$temp_clone_dir"; then
        # 复制文件
        echo "  复制文件..."
        dest_dir="$temp_clone_dir/claude-code-releases"
        mkdir -p "$dest_dir"
        cp -r "$OUTPUT_DIR"/* "$dest_dir/"

        # 提交
        echo "  提交更改..."
        cd "$temp_clone_dir"
        git add .
        if git commit -m "更新 Claude Code 到版本 $version"; then
            if git push origin master; then
                echo "  ✓ 已成功推送到 Gitee！"
            else
                echo "  错误: 推送到 Gitee 失败"
                cd ..
                exit 1
            fi
        else
            echo "  警告: 没有更改需要提交"
        fi
        cd ..

        # 清理临时目录
        rm -rf "$temp_clone_dir"
    else
        echo "错误: 克隆 Gitee 仓库失败"
        exit 1
    fi
else
    echo "使用方法:"
    echo ""
    echo "1. 上传到 Gitee Release 页面 (推荐，避免大文件限制):"
    echo "   $0 -t YOUR_GITEE_TOKEN -r https://gitee.com/iamzhihuix/claude-code-mirror.git --upload-to-release"
    echo ""
    echo "2. 提交到仓库 (传统方式):"
    echo "   $0 -c -r https://gitee.com/iamzhihuix/claude-code-mirror.git"
    echo ""
    echo "3. 手动上传:"
    echo "   - 在 Gitee 创建 Release: https://gitee.com/$repo_path/releases/new"
    echo "   - 上传 $OUTPUT_DIR 中的文件"
    echo ""
    echo "4. 测试安装:"
    echo "   ./bootstrap.sh"
fi

echo ""
echo "完成！"